﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentValidation.Results;
using Spaanjaars.ContactManager.Infrastructure.UnitOfWork;
using Spaanjaars.ContactManager.Infrastructure.Validation;
using Spaanjaars.ContactManager.Model;
using Spaanjaars.ContactManager.Services.Commands;
using Spaanjaars.ContactManager.Services.Mappers;
using Spaanjaars.ContactManager.Services.Interfaces;
using Spaanjaars.ContactManager.Services.Queries;
using Spaanjaars.ContactManager.Services.ViewModels;
using Spaanjaars.ContactManager.Services.ViewModels;

namespace Spaanjaars.ContactManager.Services.Implementations
{
    public class ContactPersonCreationService : IContactPersonCreationService
    {
        private readonly IContactPersonRepository _contactPersonRepository;
        private readonly IUnitOfWork _uow;

        public ContactPersonCreationService(IContactPersonRepository contactPersonRepository, IUnitOfWork uow)
        {
            _contactPersonRepository = contactPersonRepository;
            _uow = uow;
        }

        public CreateContactPersonCommandResult CreatePersonFrom(CreateContactPersonCommand createContactPersonCommand)
        {
            CreateContactPersonCommandResult createContactPersonCommandResult = new CreateContactPersonCommandResult();
            IEnumerable<IBrokenRule> brokenRules = new List<IBrokenRule>();

            if (createContactPersonCommand.GetValidationIssues().IsEmpty())
            {
                ContactPerson contactPerson = createContactPersonCommand.ConvertToContactPerson();

                if (contactPerson.GetBrokenRules().IsEmpty())
                {
                    _contactPersonRepository.Add(contactPerson);
                    _uow.Commit();

                    createContactPersonCommandResult = CreateSuccessfulCreateContactPersonCommandResult(contactPerson);
                }
                else
                    brokenRules = contactPerson.GetBrokenRules();
            }
            else            
                brokenRules = createContactPersonCommand.GetValidationIssues();                            

            if (!brokenRules.IsEmpty())
                createContactPersonCommandResult = CreateFailingCreateContactPersonCommandResult(brokenRules);

            return createContactPersonCommandResult;
        }

        private CreateContactPersonCommandResult CreateSuccessfulCreateContactPersonCommandResult(ContactPerson contactPerson)
        {
            CreateContactPersonCommandResult createContactPersonCommandResult =  new CreateContactPersonCommandResult();
            createContactPersonCommandResult.ContactPersonViewModel = contactPerson.ConvertToContactPersonViewModel(false);
            createContactPersonCommandResult.HasErrors = false;
            createContactPersonCommandResult.BrokenRules = new List<IBrokenRule>();

            return createContactPersonCommandResult;
        }

        private CreateContactPersonCommandResult CreateFailingCreateContactPersonCommandResult(IEnumerable<IBrokenRule> entityBrokenRules)
        {
            var createContactPersonCommandResult= new CreateContactPersonCommandResult();
            createContactPersonCommandResult.BrokenRules = entityBrokenRules;
            createContactPersonCommandResult.HasErrors = true;

            return createContactPersonCommandResult;
        }

        public int FindNumberOfPeople()
        {
            return _contactPersonRepository.Count();
        }
    }    
}
